package org.deltaset.meta.internal;

import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import org.deltaset.meta.EntityResolver;
import org.deltaset.meta.ExecutorResult;
import org.deltaset.meta.MetaAction;
import org.deltaset.meta.MetaField;
import org.deltaset.meta.annotation.DsViewType;
import org.deltaset.meta.extension.RepositoryProvider;

/**
 *
 * this should be package private class
 * BUT strange error related to visibility and reflection appears in  executor.xhtml :
 * 
 * class javax.faces.view.facelets.TagAttributeException
 *      #{meta.executorResult.isCollection()}": 
 *      java.lang.IllegalAccessException: Class javax.el.BeanELResolver can not access a member of 
 *      class org.deltaset.meta.internal.ExecutorResultImpl with modifiers "public"
 * @author dmakariev
 */
public class ExecutorResultImpl implements ExecutorResult {

    private final Object result;
    private final Class objectClass;
    private final boolean isEntity;
    private final MetaClassImpl metaClass;
    private final MetaAction executedAction;

    ExecutorResultImpl(final Object result, final MetaAction executedAction, final RepositoryProvider repositoryProvider) {
        this.result = result;
        this.executedAction = executedAction;
        this.objectClass = (null == result) ? void.class : result.getClass();
        final EntityResolver entityResolver = repositoryProvider.createEntityResolver();
        this.isEntity = entityResolver.isEntity(objectClass);//null != objectClass.getAnnotation(Entity.class);
        this.metaClass = MetaClassFactory.forClass(objectClass, repositoryProvider);//(isEntity) ? MetaClassFactory.forClass(objectClass, repositoryProvider) : null;
    }

    @Override
    public boolean isCollection() {
        return Collection.class.isAssignableFrom(objectClass);
    }

    @Override
    public boolean isEntity() {
        return isEntity;
    }

    @Override
    public List<MetaField> getDetailFields() {
        if (true == metaClass.isPrimitive()) {
            return Collections.emptyList();
        }
        return metaClass.getFieldsFor(DsViewType.DETAIL);
    }

    @Override
    public Class getResultClass() {
        return objectClass;
    }

    @Override
    public boolean isDate() {
        return Date.class.isAssignableFrom(objectClass);
    }

    @Override
    public boolean isSimple() {
        return !isCollection() && !isEntity() && !isDate();
    }

    @Override
    public Object getValue() {
        return result;
    }

    @Override
    public MetaAction getExecutedAction() {
        return executedAction;
    }
}
